/*              Copyright(c) 2008 Dave Sexton              *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using DaveSexton.DocProject;
using DaveSexton.DocProject.Sandcastle;
using DaveSexton.DocProject.Sandcastle.BuildComponents;

namespace DaveSexton.Sandcastle
{
	internal sealed class ResolveExternalLinksComponentDocProjectHost : ResolveExternalLinksComponentHost
	{
		#region Public Properties
		public override string SettingsDirectory
		{
			get
			{
				return settingsDirectory;
			}
		}

		public override string CurrentDirectory
		{
			get
			{
				return currentDirectory;
			}
		}

		internal override ApiReferenceCollection ApiReferences
		{
			get
			{
				if (references != null)
					references.EnsureLoaded();

				return references;
			}
		}
		#endregion

		#region Private / Protected
		private readonly IDocProjectHost host;
		private readonly ApiReferenceCollection references;
		private readonly string settingsDirectory, currentDirectory;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ResolveExternalLinksComponentHost" /> class.
		/// </summary>
		[System.Diagnostics.DebuggerHidden]
		private ResolveExternalLinksComponentDocProjectHost(IDocProjectHost host, IServiceProvider provider)
			: base(provider)
		{
			this.host = host;

			SandcastleSettings settings = host.Settings as SandcastleSettings;
			SandcastleProjectOptions options = host.Options as SandcastleProjectOptions;

			if (settings != null)
			{
				settingsDirectory = settings.SettingsDirectory;
				currentDirectory = settings.BuildAssemblerWorkingDirectory;

				if (options != null)
				{
					try
					{
						references = new ApiReferenceCollection(
							new ReflectionDocument(options.DocumentationSetName, settings.ReflectionXmlFile));
					}
					catch (System.IO.IOException)
					{
						// if the reflection XML file does not exist or cannot be opened then the editor's 
						// API list will remain empty
					}
				}
			}
		}
		#endregion

		#region Methods
		/// <summary>
		/// Creates a <see cref="ResolveExternalLinksComponentDocProjectHost"/> instance if DocProject 
		/// is hosting the component's editor.
		/// </summary>
		/// <remarks>
		/// Assume that DocProject is not the host if <see langword="null"/> is returned.
		/// </remarks>
		/// <returns>An <see cref="ResolveExternalLinksComponentDocProjectHost"/> instance if DocProject is hosting the 
		/// component's editor; otherwise, <see langword="null"/>.</returns>
		public static ResolveExternalLinksComponentDocProjectHost GetDocProjectHost(IServiceProvider provider)
		{
			// Do not reference host-specific interfaces in this method so that JIT compilation will always succeed, 
			// regardless of whether DocProject is installed.

			try
			{
				return GetDocProjectHostInternal(provider);
			}
			// Assume that DocProject is not installed if an exception is thrown
			catch (System.IO.FileNotFoundException) { }

			return null;
		}

		/// <summary>
		/// Attempts to retrieve the reference to an <see cref="IDocProjectHost"/> interface if DocProject
		/// is hosting the component's editor.
		/// </summary>
		/// <exception cref="System.IO.FileNotFoundException">Thrown when the JIT fails because DocProject 
		/// is not installed.</exception>
		private static ResolveExternalLinksComponentDocProjectHost GetDocProjectHostInternal(IServiceProvider provider)
		{
			IDocProjectHost host = provider.GetService(typeof(IDocProjectHost)) as IDocProjectHost;

			if (host == null)
				return null;
			else
				return new ResolveExternalLinksComponentDocProjectHost(host, provider);
		}

		public override void IncludeItemInProject(string file)
		{
			host.Project.GetItem(file).Show();
		}

		public override void CheckoutItemInProject(string file)
		{
			host.Project.GetItem(file).Checkout();
		}
		#endregion
	}
}
